// pkg/prefetch/service.go
package prefetch

import (
	"context"
	"fmt"
	"log"
	"sort"
	"sync"
	"time"
)

// AccessTrace 访问跟踪
type AccessTrace struct {
	Path      string
	Timestamp time.Time
	Size      int64
}

// AccessPattern 访问模式
type AccessPattern struct {
	Path      string
	Accesses  int
	TotalSize int64
	Heat      float64 // 热度分数 0-1
}

// Service 预取服务
type Service struct {
	traces    []AccessTrace
	mu        sync.RWMutex
	maxTraces int

	// 预取队列
	queue      chan PreFetchTask
	workers    int
	downloader Downloader
	wg         sync.WaitGroup
	done       chan struct{}
}

// PreFetchTask 预取任务
type PreFetchTask struct {
	Path     string
	Priority int
	Handler  func(data []byte, err error)
}

// Downloader 下载器接口
type Downloader interface {
	Download(ctx context.Context, path string, offset, size int64) ([]byte, error)
}

// NewService 创建预取服务
func NewService(workers int, downloader Downloader) *Service {
	return &Service{
		traces:     make([]AccessTrace, 0),
		maxTraces:  10000,
		queue:      make(chan PreFetchTask, 1000),
		workers:    workers,
		downloader: downloader,
		done:       make(chan struct{}),
	}
}

// RecordAccess 记录访问
func (s *Service) RecordAccess(path string, size int64) {
	s.mu.Lock()
	defer s.mu.Unlock()

	// 保持最近的访问记录
	if len(s.traces) >= s.maxTraces {
		s.traces = s.traces[len(s.traces)-s.maxTraces+1:]
	}

	s.traces = append(s.traces, AccessTrace{
		Path:      path,
		Timestamp: time.Now(),
		Size:      size,
	})
}

// ComputeAccessPatterns 计算访问模式
func (s *Service) ComputeAccessPatterns(ctx context.Context) ([]AccessPattern, error) {
	s.mu.RLock()
	defer s.mu.RUnlock()

	// 聚合访问统计
	patterns := make(map[string]*AccessPattern)

	for _, trace := range s.traces {
		if p, exists := patterns[trace.Path]; exists {
			p.Accesses++
			p.TotalSize += trace.Size
		} else {
			patterns[trace.Path] = &AccessPattern{
				Path:      trace.Path,
				Accesses:  1,
				TotalSize: trace.Size,
			}
		}
	}

	// 计算热度分数
	maxAccesses := 0
	for _, p := range patterns {
		if p.Accesses > maxAccesses {
			maxAccesses = p.Accesses
		}
	}

	result := make([]AccessPattern, 0, len(patterns))
	for _, p := range patterns {
		if maxAccesses > 0 {
			p.Heat = float64(p.Accesses) / float64(maxAccesses)
		}
		result = append(result, *p)
	}

	// 按热度排序
	sort.Slice(result, func(i, j int) bool {
		return result[i].Heat > result[j].Heat
	})

	return result, nil
}

// Start 启动预取服务
func (s *Service) Start(ctx context.Context) {
	for i := 0; i < s.workers; i++ {
		s.wg.Add(1)
		go s.prefetchWorker(ctx)
	}
}

// prefetchWorker 预取工作线程
func (s *Service) prefetchWorker(ctx context.Context) {
	defer s.wg.Done()

	for {
		select {
		case <-s.done:
			return
		case <-ctx.Done():
			return
		case task := <-s.queue:
			if task.Path != "" {
				// 执行预取
				data, err := s.downloader.Download(ctx, task.Path, 0, 1<<20) // 预取 1MB
				if task.Handler != nil {
					task.Handler(data, err)
				}
			}
		}
	}
}

// SubmitPrefetchTask 提交预取任务
func (s *Service) SubmitPrefetchTask(task PreFetchTask) {
	select {
	case s.queue <- task:
	case <-s.done:
	}
}

// Stop 停止预取服务
func (s *Service) Stop() {
	close(s.done)
	s.wg.Wait()
	close(s.queue)
}

// ---
